package com.jeecg.guangdian.util;

import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.Region;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;

/**
 * 自定义Excel文件导出 <BR>
 * <UL>
 * <LI>创建Sheet:自定义文件名、sheet名</LI>
 * <LI>添加内容：向sheet中的各个单元格添加内容</LI>
 * <LI>得到文件：得到定义好的文件</LI><BR>
 * </UL>
 * <BR>
 * 
 * <B>利用例: </B> <BR> 
 * 
 * <PRE>
 * 
 * String sheetName = "sheet";
 * String fileName = "资金列表"; 
 * CreateSheet createSheet=new CreateSheet(sheetName,fileName,response);
 * createSheet.addText(0,1,"aaaaa"); 
 * createSheet.addText(1,1,"bb");
 * createSheet.getFile();
 * 
 * </PRE>
 * @author HaierSoft
 * @version 1.0
 * @since 1.0
 */

public class CreateExcelFile {
    /** 日志 */
    /** 定义Workbook对象 */
    private HSSFWorkbook book = null;

    /** 定义输出流 */
    private ByteArrayOutputStream fOut = new ByteArrayOutputStream();

    /** 定义sheet */
    private HSSFSheet sheet;

    /** sheet中row对象 */
    private HSSFRow row;

    /** sheet中cell对象 */
    private HSSFCell cell;

    /** 文件名 */
    private String fileName = "Excel";

    /** 文件中sheet名 */
    private String sheetName = "sheet";

    /** HttpServletResponse */
    private HttpServletResponse response;
    private  HttpServletRequest request;
    /** 列宽度 */
    private int colWidth = 264;

    /** 行的高度 */
    private int rowHieght = 30;

    /** sheet的序号*/
    private int sheetIndex = 0;

    /** 行数的序号*/
    private int rowIndex=0;

    /**
     * 构造函数 <BR>
     * <LI>只有response 的情况</LI>
     * <LI>初始化book对象,生成workbook</LI>
     * <LI>初始化sheet对象,生成sheet</LI>
     *
     * @param response  HttpServletResponse
     * @throws Exception
     */
    public CreateExcelFile(HttpServletResponse response) throws Exception {
        // 写入日志

        // 创建Workbook对象
        book = new HSSFWorkbook();
        // 建立sheet
        sheet = book.createSheet(this.sheetName);

        HSSFPrintSetup printSetup = sheet.getPrintSetup();  //设置打印样式
        printSetup.setLandscape(true);//横版打印
        printSetup.setPaperSize(HSSFPrintSetup.A4_PAPERSIZE);  //A4打印

        sheet.setMargin(HSSFSheet.LeftMargin, (double)0.06);//左边距
        sheet.setMargin(HSSFSheet.RightMargin, (double)0.06);//右边距
        sheet.getPrintSetup().setLandscape(true);
        // 得到response
        this.response = response;
        // 写入日志

    }

    /**
     * 构造函数 <BR>
     * <LI>用户自定义文件名的情况</LI>
     * <LI>初始化book对象,生成workbook</LI>
     * <LI>初始化sheet对象,生成sheet</LI>
     *
     * @param fileName		要创建文件的文件名
     * @param response		HttpServletResponse
     * @throws Exception
     */
    public CreateExcelFile(String fileName, HttpServletResponse response)
            throws Exception {

        // 判断文件名是否为空
        if (null != fileName && !"".equals(fileName.trim())  ) {
            this.fileName = fileName;
        }
        // 创建Workbook对象
        book = new HSSFWorkbook();
        // 建立sheet
        sheet = book.createSheet(this.sheetName);
        // 得到response
        this.response = response;
        // 写入日志

    }

    /**
     * 构造函数 该方法为自定义创建Excel的方法 <BR>
     * <LI>用户自定义文件名和sheet名的情况</LI>
     * <LI>初始化book对象,生成workbook</LI>
     * <LI>初始化sheet对象,生成sheet</LI>
     *
     * @param sheetName			Excel中Sheet的名字
     * @param fileName			Excel下载时默认的文件的名字
     * @param response			HttpServletResponse
     * @throws Exception 		抛出异常
     */
    public CreateExcelFile(String sheetName, String fileName,HttpServletRequest request,
                           HttpServletResponse response) throws Exception {
        // 写入日志

        // 判断sheet名是否为空
        if (null == sheetName || "".equals(sheetName.trim())) {
            sheetName = this.sheetName;
        } else {
            char charTemp =' ';
            char[] strArray = { ':','/', '?', '*', '[', ']','：','／', '？', '＊', '［', '］'};
            // 循环去掉sheet名中的特殊符号
            for (int i = 0; i < strArray.length; i++) {
                // 得到
                int j = sheetName.indexOf(strArray[i]);
                // 如果有特殊字符
                if (j > 0) {
                    // 替换掉
                    sheetName = sheetName.replace(strArray[i], charTemp);
                }
            }
            // 判断sheet的名称是否超过31位
            if (sheetName.trim().length() > 31) {
                // 取名称的前31位
                sheetName = sheetName.substring(0, 31);
            }
        }
        // 判断文件名是否为空
        if (null != fileName && !"".equals(fileName)) {
            this.fileName = fileName;
        }
        // response是否为空
        if (null == response) {

        }
        // 创建Workbook对象
        book = new HSSFWorkbook();
        // 建立sheet
        sheet = book.createSheet();
        // 设置中文sheet名字
        book.setSheetName(0, sheetName, HSSFWorkbook.ENCODING_UTF_16);
        // 得到response
        this.response = response;
        this.request = request;
        // 写入日志

    }

    /**
     * 向一个指定单元格中添加文字
     * <UL>
     * <LI>向一个指定单元格中添加文字</LI>
     * </UL>
     * <BR>
     *
     * <B>利用例: </B> <BR>
     *
     * <PRE>
     *
     * String sheetName = "testSheet";
     * String fileName="testFile";
     * CreateExcelFile createSheet = new
     * CreateExcelFile(sheetName,fileName,response);
     * createSheet.addText(1, 1,"test,");
     * createSheet.getFile();
     *
     * </PRE>
     *
     * @param col			单元格横坐标
     * @param row			单元格纵坐标
     * @param text			要显示的文字
     * @return NULL
     */
    public void addText(int col, int row, String text){
        // 写入日志

        // 调用方法实现添加
        addText(col,row,text,null);
        // 写入日志

    }

    /**
     * 向一个单元格添加文字 并设置单元格的显示模式 <BR>
     * <UL>
     * <LI>向一个单元格添加文字 并设置单元格的显示模式</LI>
     * </UL>
     * <BR>
     *
     * <B>利用例:</B> <BR>
     *
     * <PRE>
     *
     * 设置cell中的粗体显示 加边框
     * HSSFCellStyle cellStyle =createSheet.createCellStyle();
     * cellStyle.setAlignment(HSSFCellStyle.ALIGN_RIGHT);
     * 设置底部边框
     * cellStyle.setBorderBottom(HSSFCellStyle.BORDER_DOUBLE);
     * 设置左边边框
     * cellStyle.setBorderLeft(HSSFCellStyle.BORDER_DASH_DOT);
     * 设置右边边框
     * cellStyle.setBorderRight(HSSFCellStyle.BORDER_HAIR);
     * 设置顶部边框
     * cellStyle.setBorderTop(HSSFCellStyle.BORDER_THICK);
     * 得到字体对象
     * HSSFFont font=createSheet.createFont();
     * 设置字体颜色
     * font.setColor(HSSFFont.COLOR_RED);
     * 设置为粗体
     * font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
     * cellStyle.setFont(font);
     * createSheet.addText(7, 3, "test",cellStyle);
     *
     * </PRE>
     *
     * @param col			单元格横坐标
     * @param row			单元格纵坐标
     * @param text			要显示的文字
     * @param cellStyle		单元格中文字现实模式
     * @return NULL
     */
    public void addText(int col, int row, String text,HSSFCellStyle cellStyle){
        // 写入日志

        if (null == text || "".equals(text.trim())) {
            text = "";
        }
        // 如果行数小于0  行数等于0
        if (row < 0) {
            row = 0;
        }
        // 如果列数小于0，列数等于0
        if (col < 0) {
            col = 0;
        }
        // 判断行数和列数是否合法
        if (col > 255 || row > 66535) {
            return;
        }
        // 得到行
        this.row = sheet.getRow((short) row);
        // 判断是否为空
        if (null == this.row) {
            // 新创建一行
            this.row = sheet.createRow((short) row);
        }
        // 为rowIndex赋值
        this.rowIndex=row;
        // 得到单元格
        this.cell = this.row.getCell((short) col);
        // 判断是否为空
        if (null == this.cell) {
            // 创建一个单元格
            this.cell = this.row.createCell((short) col);
        }
        // cell的类型为字符串
        cell.setCellType(HSSFCell.CELL_TYPE_STRING);
        // 设置Encoding为UTF-16
        cell.setEncoding(HSSFCell.ENCODING_UTF_16);
        // 为单元格赋值
        cell.setCellValue(text);
        // 设置格式
        if (null != cellStyle) {
            // 设置样式
            cell.setCellStyle(cellStyle);
        }
        // 写入日志


    }

    /**
     * 添加自定义的List <BR>
     * <UL>
     * <LI>自定义list</LI>
     * <LI>list中保存的必须是Map对象</LI>
     * <LI>title数组中存储的是对应list中map的头</LI>
     * <LI>key数组中存储的是对应Map中的Key</LI>
     * </UL>
     * <BR>
     *
     * <B>利用例</B><BR>
     *
     * <PRE>
     *
     * List list=new ArrayList();
     * Map map=new Hashtable();
     * String[] title={"姓名","年龄"};
     * String[] key={name,age};
     * int row=0;
     * int col=0;
     * map.put("name","Tom");
     * map.put("age","21");
     * list.add(map);
     * map=new Hashtable();
     * map.put("name","Jace");
     * map.put("age","22");
     * list.add(map);
     * 调用该方法
     * addText(list,title,key,row,col);
     *
     * </PRE>
     *
     * @param list			要导出的内容
     * @param title			导出list的头
     * @param key			list中map的key
     * @param row			显示内容开始行数
     * @param col			显示内容开始列数
     * @return      NULL
     */
    public void addText(List list, String[] title, String[] key, int row,
                        int col) {
        // 写入日志

        // 如果行数小于0  行数等于0
        if (row < 0) {
            row = 0;
        }
        // 如果列数小于0，列数等于0
        if (col < 0) {
            col = 0;
        }
        // 判断行数和列数是否合法
        if (col > 255 || row > 66535) {
            return;
        }
        // 判断list是否为空
        if (null == list || list.isEmpty()) {
            return;
        }
        // 添加具体内容
        addList(list, title, key, col, row);
        // 写入日志


    }

    /**
     * 添加自定义的List <BR>
     * <UL>
     * <LI>自定义list</LI>
     * <LI>list中保存的必须是Map对象</LI>
     * <LI>title数组中存储的是对应list中map的头</LI>
     * <LI>key数组中存储的是对应Map中的Key</LI>
     * </UL>
     * <BR>
     *
     * <B>利用例</B><BR>
     * <PRE>
     *
     * List list=new ArrayList();
     * Map map=new Hashtable();
     * String[] title={"姓名","年龄"};
     * String[] key={name,age};
     * map.put("name","Tom");
     * map.put("age","21");
     * list.add(map);
     * map=new Hashtable();
     * map.put("name","Jace");
     * map.put("age","22");
     * list.add(map);
     * 调用该方法
     * addText(list,title,key);
     *
     * </PRE>
     *
     * @param list			要导出的内容
     * @param title			导出list的头
     * @param key			list中map的key
     * @return    NULL
     */
    public void addText(List list, String[] title, String[] key){
        // 写入日志

        // 判断list是否为空
        if (null == list || list.isEmpty()) {
            return;
        }
        // 具体添加
        addList(list, title, key, 0, this.rowIndex + 1);
        // 写入日志

    }

    /**
     * 添加自定义的List <BR>
     * <UL>
     * <LI>自定义list</LI>
     * <LI>list中保存的必须是Map对象</LI>
     * <LI>key数组中存储的是对应Map中的Key</LI>
     * </UL>
     * <BR>
     *
     * <B>利用例</B><BR>
     *
     * <PRE>
     *
     * List list=new ArrayList();
     * Map map=new Hashtable();
     * String[] key={name,age};
     * int row=0;
     * int col=0;
     * map.put("name","Tom");
     * map.put("age","21");
     * list.add(map);
     * map=new Hashtable();
     * map.put("name","Jace");
     * map.put("age","22");
     * list.add(map);
     *
     * 调用该方法
     * addText(list,key,row,col);
     *
     * </PRE>
     *
     * @param list			要导出的内容
     * @param key			list中map的key
     * @param row			显示内容开始纵坐标
     * @param col			显示内容开始横坐标
     */
    public void addText(List list, String[] key, int row, int col){
        // 写入日志

        // 如果行数小于0  行数等于0
        if (row < 0) {
            row = 0;
        }
        // 如果列数小于0，列数等于0
        if (col < 0) {
            col = 0;
        }
        // 判断行数和列数是否合法
        if (col > 255 || row > 66535) {
            return;
        }
        // 判断list是否为空
        if (null == list || list.isEmpty()) {
            return;
        }
        // 添加内容
        addList(list, null, key, row, col);
        // 写入日志

    }

    /**
     * 在sheet中添加内容 <BR>
     * <UL>
     * <LI>list对象中存放的是List对象(其中存放的必须是String类型的对象)
     * 或String 类型对象</LI>
     * </UL>
     *
     * <B>利用例</B><BR>
     *
     * <PRE>
     *
     * List list=new ArrayList();
     * List listTemp=new ArrayList();
     * list.add("文件列表");
     * listTemp.add("姓名");
     * listTemp.add("年龄");
     * listTemp.add("性别");
     * list.add(listTemp);
     * listTemp=new ArrayList();
     * listTemp.add("TOM");
     * listTemp.add("22");
     * listTemp.add("男");
     * list.add(listTemp);
     *
     * 调用该方法
     * addText(list,0,0);
     *
     * </PRE>
     *
     * @param list		List对象
     * @param row		要显示内容的纵坐标
     * @param col		要显示内容的横坐标
     * @return NULL
     */
    public void addText(List list, int row, int col){
        // 写入日志

        // 如果行数小于0 行数等于0
        if (row < 0) {
            row = 0;
        }
        // 如果列数小于0，列数等于0
        if (col < 0) {
            col = 0;
        }
        // 判断行数和列数是否合法
        if (col > 255 || row > 66535) {
            return;
        }
        // 判断list是否为空
        if (null == list || list.isEmpty()) {
            return;
        }
        // 定义label
        insertList(list, row, col);
        // 写入日志

    }

    /**
     * 在sheet中添加内容 <BR>
     * <UL>
     * <LI>list对象中存放的是List对象(其中存放的必须是String类型的对象)
     * 或String 类型对象</LI>
     * </UL>
     * <BR>
     *
     * <B>利用例</B><BR>
     *
     * <PRE>
     *
     * List list=new ArrayList();
     * List listTemp=new ArrayList();
     * list.add("文件列表");
     * listTemp.add("姓名");
     * listTemp.add("年龄");
     * listTemp.add("性别");
     * list.add(listTemp);
     * listTemp=new ArrayList();
     * listTemp.add("TOM");
     * listTemp.add("22");
     * listTemp.add("男");
     * list.add(listTemp);
     *
     * 调用该方法
     * addText(list,0,0);
     *
     * </PRE>
     *
     * @param list				List对象
     * @return NULL
     */
    public void addText(List list){
        // 写入日志

        // 判断list是否为空
        if (null == list || list.isEmpty()) {
            return;
        }
        // 定义label
        insertList(list, 0, this.rowIndex+1);
        // 写入日志

    }

    /**
     * 具体实现方法<BR>
     * <UL>
     * <LI>list对象中存放的是List对象(其中存放的必须是String类型的对象)
     * 或String 类型对象</LI>
     * </UL>
     *
     * @param list				List对象
     * @param col				内容显示开始横坐标
     * @param row				内容显示开始纵坐标
     * @return NULL
     */
    private void insertList(List list, int col, int row) {
        // 写入日志

        // 判断list是否为空
        if (null == list || list.isEmpty()) {
            return;
        }
        // 中间变量
        Object obj = null;
        // 循环显示集合中的内容
        for (int i = 0; i < list.size(); i++) {
            // 得到list中的对象
            obj = list.get(i);
            // 得到行
            this.row = sheet.getRow((short) row + i);
            if (null == this.row) {
                // 生成行
                this.row = sheet.createRow((short) row + i);
            }
            // 行数赋值
            this.rowIndex = row + i;
            if (obj instanceof String) {
                // 得到map
                String strTemp = (String) obj;
                // 得到单元格
                this.cell = this.row.getCell((short) col);
                if(null==this.cell){
                    // 生成单元格
                    this.cell = this.row.createCell((short) col);
                }
                //cell的类型为字符串
                cell.setCellType(HSSFCell.CELL_TYPE_STRING);
                // 设置Encoding为UTF-16
                cell.setEncoding(HSSFCell.ENCODING_UTF_16);
                // 为单元格赋值
                cell.setCellValue(strTemp);
            } else if (obj instanceof List) {
                // 得到map
                List listTemp = (List) obj;
                if (null != listTemp && !listTemp.isEmpty()) {
                    for (int j = 0; j < listTemp.size(); j++) {
                        // 得到单元格
                        this.cell = this.row.getCell((short) (col + j));
                        if (null == this.cell) {
                            // 生成单元格
                            this.cell = this.row.createCell((short) (col + j));
                        }
                        //cell的类型为字符串
                        cell.setCellType(HSSFCell.CELL_TYPE_STRING);
                        //设置Encoding为UTF-16
                        cell.setEncoding(HSSFCell.ENCODING_UTF_16);
                        // 为单元格赋值
                        cell.setCellValue((String) listTemp.get(j));
                    }
                }
            }
        }
        // 写入日志

    }

    /**
     * 具体实现方法<BR>
     * <UL>
     * <LI>list对象中存放的是Map对象</LI>
     * <LI>title数组,Excel中显示在列表头部的内容</LI>
     * <LI>key数组中的值必须是Map的key</LI>
     * </UL>
     *
     * @param list				List对象
     * @param title				title列表显示的头
     * @param key				数组对应List中Map的key值
     * @param col				内容显示开始横坐标
     * @param row				内容显示开始纵坐标
     * @return NULL
     */
    private void addList(List list, String[] title, String[] key, int col,
                         int row) {
        // 写入日志

        // 判断list是否为空
        if (null == list || list.isEmpty()) {
            return;
        }
        // 创建对象
        Object obj = null;
        // 判断title是否为空
        if (null != title && title.length > 0 && !"".equals(title)) {
            // 得到行
            this.row = sheet.getRow((short) row);
            // 判断是否为空
            if (null == this.row) {
                // 创建标题行
                this.row = sheet.createRow((short) row);
            }
            // 为rowIndex赋值
            this.rowIndex = row;
            // 遍历数组
            for (int i = 0; i < title.length; i++) {
                // 得到单元格
                this.cell = this.row.getCell((short) (col + i));
                // 判断是否为空
                if (null == this.cell) {
                    // 创建标题列，并添加值
                    this.cell = this.row.createCell((short) (col + i));
                }
                //cell的类型为字符串
                cell.setCellType(HSSFCell.CELL_TYPE_STRING);
                //设置Encoding为UTF-16
                cell.setEncoding(HSSFCell.ENCODING_UTF_16);
                // 为单元格赋值
                cell.setCellValue(title[i]);
            }
        }
        // 循环显示集合中的内容
        for (int i = 0; i < list.size(); i++) {
            // 得到对象
            obj = list.get(i);
            // 判断对象类型
            if (obj instanceof Map) {
                // 得到map
                Map map = (Map) obj;
                // 得到行
                this.row = sheet.getRow((short) row + i + 1);
                // 判断是否为空
                if (null == this.row) {
                    // 创建行
                    this.row = sheet.createRow((short) row + i + 1);
                }
                // 重新赋值行数
                this.rowIndex = row + i + 1;
                // 判断map是否为空
                if (null != map && !map.isEmpty()) {
                    // 创建cell，并添加内容
                    for (int j = 0; j < key.length; j++) {
                        // 得到单元格
                        this.cell = this.row.getCell((short) (col + j));
                        // 判断单元格是否为空
                        if (null == this.cell) {
                            // 在各行上创建单元格
                            this.cell = this.row.createCell((short) (col + j));
                        }
                        // cell的类型为字符串
                        cell.setCellType(HSSFCell.CELL_TYPE_STRING);
                        // 设置Encoding为UTF-16
                        cell.setEncoding(HSSFCell.ENCODING_UTF_16);
                        // 为单元格赋值
                        cell.setCellValue((String) map.get(key[j]));
                    }
                }
            }
        }
        // 写入日志

    }

    /**
     * 合并sheet中的单元格<BR>
     * <UL>
     * <LI>合并中结束单元格的纵坐标必须大于开始单元格的纵坐标</LI>
     * <LI>合并中结束单元格的横坐标必须大于开始单元格的横坐标</LI>
     * <LI>各输入值不可小于0</LI>
     * <LI>纵坐标大于255,设置将无效</LI>
     * <LI>横坐标大于65535,设置将无效</LI>
     * </UL>
     * <BR>
     *
     * <B>利用例 </B><BR>
     *
     * <PRE>
     *
     * String sheetName = "testSheet";
     * String fileName="testFile";
     * CreateExcelFile createSheet = new
     * CreateExcelFile(sheetName,fileName,response);
     * createSheet.mergeCells(1,1,4,3); createSheet.addText(1, 1, "test,");
     * createSheet.getFile();
     *
     * </PRE>
     *
     * @param startCol		合并单元格开始横坐标
     * @param startRow		合并单元格开始纵坐标
     * @param endCol		合并单元格结束横坐标
     * @param endRow		合并单元格结束纵坐标
     * @retrurn NULL
     */
    public void mergeCells(int startCol, int startRow, int endCol, int endRow) {
        // 写入日志

        // 判断输入的数字是否合法
        if (startCol < 0 || startRow < 0 || endCol < 0 || endRow < 0
                || startCol > 255 || endCol > 255) {
            return;
        }
        // 合并单元格
        sheet.addMergedRegion(new Region(startRow, (short) startCol, endRow,
                (short) endCol));
        // 写入日志

    }

    /**
     * 得到自定义的Excel文件<BR>
     * <UL>
     * <LI>此方法是下载自定义的sheet文件</LI>
     * <LI>设置完要得到的Excel后，必须调用此方法才能下载</LI>
     * </UL>
     * <BR>
     *
     * <B>利用例 </B><BR>
     *
     * <PRE>
     *
     * String sheetName = "testSheet";
     * String fileName="testFile";
     * CreateExcelFile createSheet = new
     * CreateExcelFile(sheetName,fileName,response);
     * createSheet.addText(1, 1, "test,");
     * createSheet.getFile();
     *
     * </PRE>
     *
     * @return NULL
     * @throws Exception
     */
    public void getFile() throws Exception{
        // 写入日志

        // 把配置好的Excel写入输出流
        book.write(fOut);
        // 定义byte数组
        byte[] bytearray = null;
        // 数组转化
        bytearray = fOut.toByteArray();
        // 设置为下载模式
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("UTF-8");
        // 设置页面缓存
        response.setHeader("Cache-Control", "");
        // 设置response 长度
        response.setContentLength(bytearray.length);
        fileName = fileName+".xls";
        // 设置默认下载文件名
       // response.setHeader("Content-Disposition",
       //"attachment; filename=\"" +  new String(fileName.getBytes("utf-8"), "GBK") + ".xls" + "\"")
                        ;
        String browser = request.getHeader("User-Agent");
        if (-1 < browser.indexOf("MSIE 6.0") || -1 < browser.indexOf("MSIE 7.0")) {
            // IE6, IE7 浏览器
            response.addHeader("content-disposition", "attachment;filename="
                    + new String(fileName.getBytes(), "ISO8859-1"));
        } else if (-1 < browser.indexOf("MSIE 8.0")) {
            // IE8
            response.addHeader("content-disposition", "attachment;filename="
                    + URLEncoder.encode(fileName, "UTF-8"));
        } else if (-1 < browser.indexOf("MSIE 9.0")) {
            // IE9
            response.addHeader("content-disposition", "attachment;filename="
                    + URLEncoder.encode(fileName, "UTF-8"));
        } else if (-1 < browser.indexOf("Chrome")) {
            // 谷歌
            response.addHeader("content-disposition",
                    "attachment;filename*=UTF-8''" + URLEncoder.encode(fileName, "UTF-8"));
        } else if (-1 < browser.indexOf("Safari")) {
            // 苹果
            response.addHeader("content-disposition", "attachment;filename="
                    + new String(fileName.getBytes(), "ISO8859-1"));
        } else {
            // 火狐或者其他的浏览器
            response.addHeader("content-disposition",
                    "attachment;filename*=UTF-8''" + URLEncoder.encode(fileName, "UTF-8"));
        }
        // 定义输出流
        OutputStream outStream = response.getOutputStream();
        // 输出
        outStream.write(bytearray, 0, bytearray.length);
        // 关闭输出流
        outStream.close();
        response.setHeader("Cache-Control", "no_store");
        // 写入日志

    }

    /**
     * 设置指定列的宽度<BR>
     * <UL>
     * <LI>设置指定列的宽度</LI>
     * </UL>
     * <BR>
     *
     * <B>利用例 </B><BR>
     *
     * <PRE>
     *
     * String sheetName = "testSheet";
     * String fileName="testFile";
     * CreateExcelFile createSheet = new
     * CreateExcelFile(sheetName,fileName,response);
     * createSheet.setColWidth(2,34);
     * createSheet.addText(1, 1, "test,");
     * createSheet.getFile();
     *
     * </PRE>
     *
     * @param 	cols			要设置宽度的列
     * @param 	colWidth		要设置的宽度
     * @return NULL
     */
    public void setColWidth(int cols, int colWidth) {
        // 写入日志

        // 变量
        int widthTemp=0;
        //  当要设置的宽度大于200或小于0 宽度恢复为初始值
        if (colWidth <= 0 || colWidth > 200) {
            widthTemp = 300 * 10;
        } else {
            widthTemp = this.colWidth * colWidth;
        }
        // 如果要设置的列为小于0 列数为0
        if (cols < 0 || cols > 255) {
            cols = 0;
        }
        // 设置宽度
        sheet.setColumnWidth((short)cols, (short)widthTemp);
        // 写入日志

    }

    /**
     * 设置行的高度<BR>
     * <UL>
     * <LI>row必须大于0小于65535</LI>
     * </UL>
     * <BR>
     *
     * <B>利用例 </B><BR>
     *
     * <PRE>
     *
     * String sheetName = "testSheet";
     * String fileName="testFile";
     * CreateExcelFile createSheet = new
     * CreateExcelFile(sheetName,fileName,response);
     * createSheet.setColWidth(2,34);
     * createSheet.addText(1, 1, "test,");
     * createSheet.setRowHieght(2,34);
     * createSheet.getFile();
     *
     * </PRE>
     *
     * @param row			要设置高度的行
     * @return NULL
     */
    public void setRowHieght(int row,int rowHeight){
        // 写入日志

        // 变量
        int heigthTemp=0;
        // 判断行数是否合法
        if (row < 0 || row > 65535) {
            return;
        }
        // 如果高度大于1000或小于0 高度恢复为初始值
        if (rowHieght <= 0 || rowHieght > 300) {
            heigthTemp = this.rowHieght * 10;
        } else {
            // 高度转换
            heigthTemp = rowHeight * this.rowHieght;
        }
        // 定义行
        HSSFRow rowTemp = sheet.getRow(row);
        // 判断row是否为空
        if (null == rowTemp) {
            rowTemp = sheet.createRow(row);
        }
        // 设置行的高度
        rowTemp.setHeight((short) heigthTemp);
        // 写入日志

    }

    /**
     * 创建新的sheet<BR>
     * <UL>
     * <LI>创建新的sheet，sheet名字不能为空</LI>
     * </UL>
     * <BR>
     *
     * <B>利用例 </B><BR>
     *
     * <PRE>
     *
     * String sheetName = "testSheet";
     * String fileName="testFile";
     * CreateExcelFile createSheet = new
     * CreateExcelFile(sheetName,fileName,response);
     * createSheet.addText(1, 1, "test,");
     * createSheet.createNewSheet("test1");
     * createSheet.addText(1, 1, "test1,text");
     * createSheet.getFile();
     *
     * </PRE>
     *
     * @param sheetName 	sheet的名字
     * @return return 		NULL
     */
    public void createNewSheet(String sheetName) {
        // 写入日志

        // 默认sheet数加一
        sheetIndex = sheetIndex + 1;
        // 判断sheet名字是否为空
        if (null == sheetName || "".equals(sheetName.trim())) {
            sheetName = this.sheetName + sheetIndex;
        }else {
            // 要替换成的值
            char charTemp =' ';
            // 要替换的字符
            char[] strArray = { ':','/', '?', '*', '[', ']','：','／', '？', '＊', '［', '］'};
            // 循环去掉sheet名中的特殊符号
            for (int i = 0; i < strArray.length; i++) {
                // 得到是否有特殊字符
                int j = sheetName.indexOf(strArray[i]);
                // 如果有特殊字符
                if (j > 0) {
                    // 替换掉
                    sheetName = sheetName.replace(strArray[i], charTemp);
                }
            }
            // 判断sheet的名称是否超过31位
            if (sheetName.trim().length() > 31) {
                // 取名称的前31位
                sheetName = sheetName.substring(0, 31);
            }
        }
        // 得到sheet
        sheet = book.getSheet(sheetName);
        // 判断sheet是否为空
        if (null == sheet) {
            // 建立sheet
            sheet = book.createSheet();
            // 为新sheet命名
            book.setSheetName(sheetIndex,sheetName,HSSFWorkbook.ENCODING_UTF_16);
        }
        // 初始化rowIndex
        this.rowIndex=0;
        // 写入日志

    }

    /**
     * 冻结指定的单元格<BR>
     * <UI>
     * <LI>row必须大于0小于65535</LI>
     * <LI>col必须大于0小于255</LI>
     * </UL>
     * <BR>
     * <B>利用例 </B><BR>
     *
     * <PRE>
     *
     * String sheetName = "testSheet"; 
     * String fileName="testFile"; 
     * CreateExcelFile createSheet = new
     * CreateExcelFile(sheetName,fileName,response);
     * createSheet.addText(1, 1, "test,");
     * createSheet.createFreezePane(3,3);
     * createSheet.getFile();
     *
     * </PRE>
     *
     * @param col		要冻结的列
     * @param row		要冻结的行
     * @return NULL
     */
    public void createFreezePane(int col, int row) {
        // 写入日志

        // 如果行数小于0 行数等于0
        if (row < 0) {
            row = 1;
        }
        // 如果列数小于0，列数等于0
        if (col < 0) {
            col = 0;
        }
        // 如果行数大于65535 如果列数大于255
        if (row > 65535 || col > 255) {
            return;
        }
        // 冻结单元格
        sheet.createFreezePane(col, row);
        // 写入日志

    }

    /**
     * 得到指定sheet<BR>
     * <UI>
     * <LI>得到指定sheet</LI>
     * </UL>
     * <BR>
     *
     * <B>利用例 </B>
     *
     * <PRE>
     *
     * String sheetName = "testSheet"; 
     * String fileName="testFile"; 
     * CreateExcelFile createSheet = new
     * CreateExcelFile(sheetName,fileName,response);
     * createSheet.addText(1, 1, "test,");
     * createSheet.getSheet("testSheet");
     * createSheet.addText(1, 1, "testTest,");
     * createSheet.getFile();
     *
     * </PRE>
     *
     * @param sheetName		sheet的名字
     * @return NULL
     */
    public void getSheet(String sheetName) {
        // 写入日志

        // 判断sheetName是否为空
        if (null == sheetName || "".equals(sheetName.trim())) {
            sheetName = this.sheetName + sheetIndex;
        }
        // 得到指定的sheet
        sheet = book.getSheet(sheetName);
        // 判断sheet是否为空
        if (null == sheet) {
            createNewSheet(sheetName);
        }
        // 初始化行的序号
        this.rowIndex = 0;
        // 写入日志

    }

    /**
     * 设置指定列的样式<BR>
     * <UL>
     * <LI>col必须大于0,小于255</LI>
     * <LI>cellStyle必须不为空</LI>
     * </UL>
     * <BR>
     *
     * <B>利用例： <B><BR>
     *
     * <PRE>
     *
     * String sheetName = "testSheet"; 
     * String fileName="testFile";
     * CreateExcelFile createSheet = new
     * CreateExcelFile(sheetName,fileName,response); 
     * HSSFCellStyle cellStyle =createSheet.createCellStyle();
     * cellStyle.setAlignment(HSSFCellStyle.ALIGN_RIGHT);
     * createSheet.setColStyle(2,cellStyle); 
     * createSheet.addText(1, 1, "test,");
     * createSheet.addText(2, 1, "test,"); 
     * createSheet.getFile();
     *
     * </PRE>
     *
     * @param col			指定的列
     * @param cellStyle		要设置的样式
     * @return NULL
     * @deprecated 尽量不要用
     */
    public void setColStyle(int col, HSSFCellStyle cellStyle) {
        // 写入日志

        // 判断是否小于0
        if (col < 0 || col > 225) {
            col = 0;
        }
        // 判断样式是否为空
        if (null == cellStyle) {
            return;
        }
        // 定义行对象
        HSSFRow rowTemp = null;
        // 定义单元格对象
        HSSFCell cellTemp = null;
        // 循环设置格式
        for (int i = 0; i < 65536; i++) {
            // 得到行
            rowTemp = sheet.getRow((short) i);
            // 判断行对象是否为空
            if (null == rowTemp) {
                // 生成行
                rowTemp = sheet.createRow((short) i);
            }
            // 得到单元格
            cellTemp = rowTemp.getCell((short) col);
            // 判断单元格是否为空
            if (null == cellTemp) {
                // 创建单元格
                cellTemp = rowTemp.createCell((short) col);
            }
            // 设置单元格的样式
            cellTemp.setCellStyle(cellStyle);
        }
        // 写入日志

    }

    /**
     * 设置一指定行的格式<BR>
     * <UL>
     * <LI>row必须大于0,小于65536</LI>
     * <LI>cellStyle必须不为空</LI>
     * </UL>
     * <BR>
     *
     * <B>利用例： <B><BR>
     *
     * <PRE>
     *
     * String sheetName = "testSheet"; 
     * String fileName="testFile";
     * CreateExcelFile createSheet = new
     * CreateExcelFile(sheetName,fileName,response); 
     * HSSFCellStyle cellStyle =createSheet.createCellStyle();
     * cellStyle.setAlignment(HSSFCellStyle.ALIGN_RIGHT);
     * createSheet.setRowStyle(1,cellStyle); 
     * createSheet.addText(1, 1, "test,");
     * createSheet.addText(2, 1, "test,"); 
     * createSheet.getFile();
     *
     * </PRE>
     *
     * @param row			指定的行
     * @param cellStyle		要设置的样式
     * @return NULL
     * @deprecated			尽量不要用
     */
    public void setRowStyle(int row, HSSFCellStyle cellStyle) {
        // 写入日志

        // 判断是否小于0
        if (row < 0 || row > 65536) {
            row = 0;
        }
        // 判断样式是否为空
        if (null == cellStyle) {
            return;
        }
        // 定义行对象
        HSSFRow rowTemp = null;
        // 定义单元格对象
        HSSFCell cellTemp = null;
        // 得到行
        rowTemp = sheet.getRow((short) row);
        // 判断是否为空
        if (null == rowTemp) {
            // 创建行
            rowTemp = sheet.createRow((short) row);
        }
        // 循环设置格式
        for (int i = 0; i < 255; i++) {
            // 得到单元格
            cellTemp = rowTemp.getCell((short) i);
            // 判断是否为空
            if (null == cellTemp) {
                // 创建单元格
                cellTemp = rowTemp.createCell((short) i);
            }
            // 设置样式
            cellTemp.setCellStyle(cellStyle);
        }
        // 写入日志

    }

    /**
     * 得到样式实例<BR>
     * <UL>
     * <LI>得到样式实例</LI>
     * </UI>
     * <BR>
     *
     * <B>利用例： <B><BR>
     *
     * <PRE>
     *
     * String sheetName = "testSheet"; 
     * String fileName="testFile";
     * CreateExcelFile createSheet = new
     * CreateExcelFile(sheetName,fileName,response); 
     * HSSFCellStyle cellStyle =createSheet.createCellStyle();
     * cellStyle.setAlignment(HSSFCellStyle.ALIGN_RIGHT);
     * createSheet.setRowStyle(1,cellStyle); 
     * createSheet.addText(1, 1, "test,");
     * createSheet.addText(2, 1, "test,"); 
     * createSheet.getFile();
     *
     * </PRE>
     *
     * @return		HSSFCellStyle	样式对象
     */
    public HSSFCellStyle createCellStyle() {
        // 写入日志

        // 返回样式对象
        return book.createCellStyle();
    }

    /**
     * 生成字体对象<BR>
     * <UL>
     * <LI>生成字体对象</LI>
     * </UL>
     *
     * <B>利用例： <B><BR>
     *
     * <PRE>
     *
     * String sheetName = "testSheet"; 
     * String fileName="testFile";
     * CreateExcelFile createSheet = new
     * CreateExcelFile(sheetName,fileName,response); 
     * HSSFCellStyle cellStyle =createSheet.createCellStyle();
     * cellStyle.setAlignment(HSSFCellStyle.ALIGN_RIGHT);
     * HSSFFont font=createSheet.createFont();
     * font.setColor(HSSFFont.COLOR_RED);
     * cellStyle.setFont(font);
     * createSheet.setRowStyle(1,cellStyle); 
     * createSheet.addText(1, 1, "test,");
     * createSheet.addText(2, 1, "test,"); 
     * createSheet.getFile();
     *
     * </PRE>
     *
     * @return		HSSFFont		字体对象 
     */
    public HSSFFont createFont() {
        // 写入日志

        // 返回字体对象
        return book.createFont();
    }

    /**
     * 日期格式对象<BR>
     * <UL>
     * <LI>日期格式对象</LI>
     * </UI>
     * <BR>
     *
     * <B>利用例： <B><BR>
     *
     * <PRE>
     *
     * String sheetName = "testSheet"; 
     * String fileName="testFile";
     * CreateExcelFile createSheet = new
     * CreateExcelFile(sheetName,fileName,response); 
     * HSSFCellStyle cellStyle =createSheet.createCellStyle();
     * cellStyle.setAlignment(HSSFCellStyle.ALIGN_RIGHT);
     * HSSFDataFormat format = createSheet.createDataFormat();
     * cellStyle.setDataFormat(format.getFormat("mm-dd"));
     * createSheet.addText(1, 1, "2006-4-12",cellStyle);
     * createSheet.addText(2, 1, "test,"); 
     * createSheet.getFile();
     *
     * </PRE>
     *
     * @return		HSSFDataFormat		日期格式对象 
     */
    public HSSFDataFormat createDataFormat() {
        // 写入日志

        // 返回日期格式对象
        return book.createDataFormat();
    }
}